package io.jnet.server.accepthandler.impl;

import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutorService;
import io.jnet.common.api.AioListener;
import io.jnet.common.api.ChannelContext;
import io.jnet.common.build.ChannelContextBuilder;
import io.jnet.common.build.ChannelContextConfig;
import io.jnet.common.businessprocessor.MutlisAttachProcessor;
import io.jnet.common.channelcontext.MutliAttachChannelContext;

public class MutliAttachAcceptHandler extends AbstractAcceptHandler
{
    private MutlisAttachProcessor[] processors;
    private long                    index = 0;
    private final int               mask;
    
    public MutliAttachAcceptHandler(int size, ExecutorService businessExecutorService, AsynchronousServerSocketChannel serverSocketChannel, ChannelContextBuilder channelContextBuilder, AioListener serverListener)
    {
        super(businessExecutorService, serverSocketChannel, channelContextBuilder, serverListener);
        processors = new MutlisAttachProcessor[size];
        for (int i = 0; i < size; i++)
        {
            processors[i] = new MutlisAttachProcessor(serverListener);
            businessExecutorService.execute(processors[i]);
        }
        mask = size - 1;
    }
    
    @Override
    protected ChannelContext parse(ExecutorService businessExecutorService, AsynchronousSocketChannel socketChannel, ChannelContextConfig config, AioListener listener)
    {
        MutlisAttachProcessor processor = processors[(int) (index & mask)];
        index += 1;
        ChannelContext serverChannelContext = new MutliAttachChannelContext(//
                processor, //
                businessExecutorService, //
                config.getBufStorage(), //
                config.getMaxMerge(), //
                listener, //
                config.getInProcessors(), //
                config.getOutProcessors(), //
                socketChannel, //
                config.getFrameDecodec());
        return serverChannelContext;
    }
    
}
